import { Controller, Get, Post, Put, Delete, Body, Param, Query, UseGuards, Req, HttpStatus, UnauthorizedException, HttpCode } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, ApiParam } from '@nestjs/swagger';
import { TaskService } from './task.service';
import { CreateTaskDto } from './dto/create-task.dto';
import { UpdateTaskDto } from './dto/update-task.dto';
import { TaskResponseDto } from './dto/task-response.dto';
import { JwtAuthGuard } from '../../guards/jwt-auth.guard';
import { PermissionsGuard } from '../../guards/permissions.guard';
import { Permissions } from '../../decorators/permissions.decorator';
import { TaskStatus, Priority } from '../../types/enums';
import { plainToClass } from 'class-transformer';
import { Request } from 'express';

interface RequestWithUser extends Request {
  user: {
    id: string;
    [key: string]: any;
  };
}

@ApiTags('任务管理')
@Controller('tasks')
@UseGuards(JwtAuthGuard, PermissionsGuard)
@ApiBearerAuth()
export class TaskController {
  constructor(private readonly taskService: TaskService) {}

  @Post()
  @Permissions('task:create')
  @ApiOperation({ summary: '创建任务' })
  @ApiResponse({
    status: HttpStatus.CREATED,
    description: '任务创建成功',
    type: TaskResponseDto,
  })
  async createTask(
    @Body() createTaskDto: CreateTaskDto,
    @Req() req: RequestWithUser,
  ): Promise<TaskResponseDto> {
    if (!req.user) {
      throw new UnauthorizedException('用户未认证');
    }
    
    const userId = req.user.id;
    
    const task = await this.taskService.createTask(
      createTaskDto.title,
      createTaskDto.description,
      createTaskDto.projectId,
      new Date(createTaskDto.startDate),
      new Date(createTaskDto.dueDate),
      userId,
      createTaskDto.status,
      createTaskDto.priority,
      createTaskDto.assigneeId,
    );
    
    return plainToClass(TaskResponseDto, task);
  }

  @Get()
  @Permissions('task:read')
  @ApiOperation({ summary: '获取任务列表' })
  @ApiQuery({
    name: 'projectId',
    required: false,
    description: '项目ID',
    type: String,
  })
  @ApiQuery({
    name: 'status',
    required: false,
    description: '任务状态',
    enum: TaskStatus,
  })
  @ApiQuery({
    name: 'priority',
    required: false,
    description: '优先级',
    enum: Priority,
  })
  @ApiQuery({
    name: 'assigneeId',
    required: false,
    description: '指派人ID',
    type: String,
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '获取任务列表成功',
    type: [TaskResponseDto],
  })
  async getTasks(
    @Query('projectId') projectId?: string,
    @Query('status') status?: TaskStatus,
    @Query('priority') priority?: Priority,
    @Query('assigneeId') assigneeId?: string,
  ): Promise<TaskResponseDto[]> {
    let tasks: any[];
    
    if (projectId) {
      tasks = await this.taskService.getTasksByProject(projectId, status, priority, assigneeId);
    } else {
      tasks = await this.taskService.getAllTasks(status, priority, assigneeId);
    }
    
    return tasks.map(task => plainToClass(TaskResponseDto, task));
  }

  @Get(':id')
  @Permissions('task:read')
  @ApiOperation({ summary: '获取任务详情' })
  @ApiParam({
    name: 'id',
    description: '任务ID',
    type: String,
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '获取任务详情成功',
    type: TaskResponseDto,
  })
  @ApiResponse({
    status: HttpStatus.NOT_FOUND,
    description: '任务不存在',
  })
  async getTaskById(@Param('id') id: string): Promise<TaskResponseDto> {
    const task = await this.taskService.getTaskById(id);
    return plainToClass(TaskResponseDto, task);
  }

  @Put(':id')
  @Permissions('task:update')
  @ApiOperation({ summary: '更新任务' })
  @ApiParam({
    name: 'id',
    description: '任务ID',
    type: String,
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '任务更新成功',
    type: TaskResponseDto,
  })
  @ApiResponse({
    status: HttpStatus.NOT_FOUND,
    description: '任务不存在',
  })
  async updateTask(
    @Param('id') id: string,
    @Body() updateTaskDto: UpdateTaskDto,
  ): Promise<TaskResponseDto> {
    const startDate = updateTaskDto.startDate ? new Date(updateTaskDto.startDate) : undefined;
    const dueDate = updateTaskDto.dueDate ? new Date(updateTaskDto.dueDate) : undefined;
    
    const task = await this.taskService.updateTask(
      id,
      updateTaskDto.title,
      updateTaskDto.description,
      updateTaskDto.status,
      updateTaskDto.priority,
      updateTaskDto.assigneeId,
      startDate,
      dueDate,
    );
    
    return plainToClass(TaskResponseDto, task);
  }

  @Put(':id/status')
  @Permissions('task:update:status')
  @ApiOperation({ summary: '更新任务状态' })
  @ApiParam({
    name: 'id',
    description: '任务ID',
    type: String,
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '任务状态更新成功',
    type: TaskResponseDto,
  })
  @ApiResponse({
    status: HttpStatus.NOT_FOUND,
    description: '任务不存在',
  })
  async updateTaskStatus(
    @Param('id') id: string,
    @Body('status') status: TaskStatus,
  ): Promise<TaskResponseDto> {
    const task = await this.taskService.updateTaskStatus(id, status);
    return plainToClass(TaskResponseDto, task);
  }

  @Delete(':id')
  @Permissions('task:delete')
  @ApiOperation({ summary: '删除任务（软删除）' })
  @ApiParam({
    name: 'id',
    description: '任务ID',
    type: String,
  })
  @ApiResponse({
    status: HttpStatus.OK,
    description: '任务删除成功',
  })
  @ApiResponse({
    status: HttpStatus.NOT_FOUND,
    description: '任务不存在',
  })
  async deleteTask(@Param('id') id: string): Promise<{ message: string }> {
    return this.taskService.deleteTask(id);
  }

  @Delete(':id/permanent')
  @Permissions('task:delete:permanent')
  @HttpCode(HttpStatus.NO_CONTENT)
  @ApiOperation({ summary: '永久删除任务' })
  @ApiParam({
    name: 'id',
    description: '任务ID',
    type: String,
  })
  @ApiResponse({
    status: HttpStatus.NO_CONTENT,
    description: '任务永久删除成功',
  })
  @ApiResponse({
    status: HttpStatus.NOT_FOUND,
    description: '任务不存在',
  })
  async permanentDeleteTask(@Param('id') id: string) {
    await this.taskService.permanentDeleteTask(id);
  }
}